package DataStructure.StackLearning.StackArray;

/**
 * 集合类:
 * 实现一个栈: 利用数组
 */
public class MyStackArray<T> {

    private int MAX_CAPACITY = Integer.MAX_VALUE - 8;
    // private int INIT_CAPACITY = 10;
    private Object [] arr;// 栈的底层数组
    private int size;

    public MyStackArray() {
        arr = new Object[10];
    }
    public MyStackArray(int initCapacity){
        if (initCapacity <= 0 || initCapacity > MAX_CAPACITY){
            // 如果参数不合法
            throw new IllegalArgumentException("initCapacity = " + initCapacity);
        }
        arr = new Object[initCapacity];
    }

    public boolean push(T t){
        if (t == null) throw new IllegalArgumentException("parame is null");
        // 判断数组是否需要扩容
        if (size == arr.length){// 数组存储满
            int newLen = getLen();// 获取一个新长度
            grow(newLen); // 扩容数组
        }

        // arr是一个不满的数组, 可以添加,
        arr[size++] = t;
        return true;
    }

    private void grow(int newLen) {

        // 创建一个新数组
        Object[] objects = new Object[newLen];
        // 把旧数组的数据转移到新数组
        for (int i = 0; i < arr.length; i++) {
            objects[i] = arr[i];
        }

        // 把新数组赋值给arr
        arr = objects;

    }

    private int getLen() {
        // 获取一个新的扩容长度
        int oldLen = arr.length;
        //int newLen = oldLen << 1;// 新长度是旧长度的两倍
        // 如果长度为1，则要更改，否则位运算不会进行扩容
        if(oldLen == 1) {
            oldLen = 2;
        }
         int newLen = oldLen + (oldLen >> 1); // 新长度是旧长度的1.5倍数

        if (newLen < 0  || newLen > MAX_CAPACITY){
            // 新扩容的参数太大了.
            newLen = MAX_CAPACITY;
        }

        if (oldLen == newLen){
            // 组数只能这么大了
            throw  new RuntimeException("arr is max");
        }

        return newLen;
    }


    public T pop(){
        if (isEmpty()){
            return null;
        }

        T oldValue = (T)arr[size-1];
        size--;

        return oldValue;
    }


    public T peek(){
        if (isEmpty()){
            return null;
        }

        return (T)arr[size - 1];
    }




    public boolean isEmpty() {
        return size == 0;
    }


}
